package miniMVC.patterns
{
	import flash.events.Event;
	
	import miniMVC.i.IBinder;
	import miniMVC.i.IFacade;
	import miniMVC.i.IRichDispatcher;
	import miniMVC.i.ISender;
	

	/**
	 * 本外观工厂和pureMVC差不多,主要有注册的监听对象而使用,本工厂是个单例,是程序的单入口
	 * @author pelephone
	 * @web http://cnblogs.com/pelephone
	 * @email pelephone@163.com
	 */	
	public class Facade implements IFacade, ISender
	{
		public static const ALL_CMD_INIT:String = "all_cmd_init";
		// 用于存放对象便于调用
		private var bindHm:Object = new Object();
//		private var listenerHm:ListenerMgr;
		private var dispatch:IRichDispatcher;
		
		protected static var instance : Facade;
		
		/**
		 * 构造外观
		 */
		public function Facade()
		{
			if (instance != null) throw Error("此单例已经存在了");
			instance = this;
//			listenerHm = new ListenerMgr();
			dispatch = new RichEventDispatcher(this);
			sendNote(ALL_CMD_INIT);
		}
		
		public static function getInstance():Facade {
			if (instance == null) instance = new Facade( );
			return instance;
		}
		
		/**被观察对象覆盖此函初始并注册
		protected function onConfigInject():void
		{
		}*/
		
		public function addEventListener(type:String, listener:Function
								, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			dispatch.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			dispatch.removeEventListener(type, listener, useCapture);
		}
		
		/**
		 * 监听
		 * @param type
		 * @param listener
		 * @param priority
		 * @param useWeakReference
		 
		public function addListener(type:String, listener:Function
									, priority:int=0, useWeakReference:Boolean=false):void
		{
			listenerHm.addListener(type,listener);
			super.addEventListener(type,listener,false,priority,useWeakReference);
		}*/
		
		/**
		 * 移除事件
		 * @param type
		 * @param listener
		 
		public function removeListener(type:String, listener:Function):void
		{
			listenerHm.removeListener(type,listener);
			super.removeEventListener(type,listener);
		}*/
		
		/**
		 * 移出某消息的所有监听函数
		 * @param type
		 */
		public function removeTypeListeners(type:String):void
		{
			dispatch.removeTypeListeners(type);
		}
		
		/**
		 * 移出所有监听函数
		 */
		public function removeAllListeners():void
		{
			dispatch.removeAllListeners();
		}
		
		/**
		 * 发送
		 * @param type
		 * @param obj
		 * @param bubbles
		 * @param cancelable
		 */
		public function sendNote(type:String,obj:Object=null,cancelable:Boolean=false):void
		{
			dispatch.dispatchEvent(new Note(type,obj,false,cancelable));
		}
		
		/**
		 * 拖管发送消息
		 * @param note
		 
		public function dispatchNote(note:Note):void
		{
			dispatch.dispatchEvent(note);
		}*/
		
		public function dispatchEvent(event:Event):Boolean
		{
			return dispatch.dispatchEvent(event);
		}
		
		public function hasEventListener(type:String):Boolean
		{
			return dispatch.hasEventListener(type);
		}
		
		public function willTrigger(type:String):Boolean
		{
			return dispatch.willTrigger(type);
		}
		
		////////////////////////////////
		// 注册和set/get
		///////////////////////////////
		
/*		public function getController(controllerName:String):IController
		{
			return bindHm[controllerName] as IController;
		}
		
		public function getModel(modelName:String):IModel
		{
			return bindHm[modelName] as IModel;
		}
		
		public function getView(viewName:String):IView
		{
			return bindHm[viewName] as IView;
		}
		
		public function hasController(controllerName:String):Boolean
		{
			return (bindHm[controllerName] as IController)!=null;
		}
		
		public function hasModel(modelName:String):Boolean
		{
			return (bindHm[modelName] as IModel)!=null;
		}
		
		public function hasView(viewName:String):Boolean
		{
			return (bindHm[viewName] as IView)!=null;
		}
		
		public function registerModel(model:IModel):void
		{
			registerBinder(model.getName(),model);
		}
		
		public function registerController(controller:IController):void
		{
			registerBinder(controller.getName(),controller);
			for each (var type:String in controller.registerlistNotes()) 
			{
				addListener(type,controller.handleNotes);
			}
		}
		
		public function registerView(view:IView):void
		{
			registerBinder(view.getName(),view);
			for each (var type:String in view.registerlistNotes()) 
			{
				addListener(type,view.handleNotes);
			}
		}*/
		
		/**
		 * 将对象绑定在facade上,供查找
		 * @param bindName
		 * @param binder
		 */
		public function registerBinder(bindName:String,binder:IBinder):void
		{
			if(hasBinder(bindName)){
				trace(bindName,"名已有绑定对象,自动覆盖!");
			}
			bindHm[bindName] = binder;
			binder.onRegister();
		}
		
		/**
		 * 是该名字是否定有对象
		 * @param bindName
		 * @return 
		 */
		public function hasBinder(bindName:String):Boolean
		{
			return bindHm[bindName]!=null;
		}
		
		/**
		 * 获取绑定在facade上的绑定对象
		 * @param controllerName
		 * @return 
		 */
		public function getBinder(bindName:String):IBinder
		{
			return bindHm[bindName] as IBinder;
		}
		
		/**
		 * 移除绑定在facade上面的mvc对象
		 * @param bindName
		 */
		public function removeBinder(bindName:String):IBinder
		{
			var binder:IBinder = bindHm [ bindName ] as IBinder;
			if ( binder ) 
			{
				bindHm[ bindName ] = null;
				binder.onRemove();
				delete bindHm[bindName];
			}
			return binder;
		}
		
		public function dispose():void
		{
			bindHm = {};
			removeAllListeners();
		}
		
		public function dispatchNote(event:Event):Boolean
		{
			return dispatchEvent(event);
		}
	}
}